package su.theravada.jpalireader;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.GroupLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

import su.theravada.jpalireader.entities.AppState;
import su.theravada.jpalireader.entities.NodeInfo;
import su.theravada.jpalireader.entities.AppState.OpenBookInfo;
import su.theravada.jpalireader.openBookDlg.OpenBookDlg;
import su.theravada.jpalireader.util.SqlUtil;
import su.theravada.jpalireader.util.UTF8Control;


/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class MainWindow extends javax.swing.JFrame {
	private JToolBar ctlToolBar;
	private JButton ctlSearchTipitaka;
	private JButton ctlToggleDictionary;
	private JSplitPane ctlMainWindowSplitter;
	private JButton ctlExit;
	private JTabbedPane ctlTopTabPane;
	private JTabbedPane ctlBottomTabPane;
	private OpenBookDlg m_dlgOpenBook;
	private DictionaryPanel ctlDictionary;
	public AppState appState;
	private String _settingsFileName="settings.ser";
	
	private static Connection m_objConnection;
	
    private static String driver = "org.apache.derby.jdbc.EmbeddedDriver";   
    private static boolean IsDebug=false;
    
    private static final Logger _HtmlBlockPanelLogger=Logger.getLogger("org.lobobrowser.html.gui.HtmlBlockPanel"); 
	private static final Logger _HTMLLinkElementImplLogger = Logger.getLogger("org.lobobrowser.html.domimpl.HTMLLinkElementImpl");
	private static final Logger _HTMLDocumentImplLogger = Logger.getLogger("org.lobobrowser.html.domimpl.HTMLDocumentImpl");
	private static final Logger _HTMLHtmlElementImplLogger = Logger.getLogger("org.lobobrowser.html.domimpl.HTMLHtmlElementImpl");
	private static final Logger _RBlockLogger = Logger.getLogger("org.lobobrowser.html.renderer.RBlock");	
	private static final Logger _HtmlControllerLogger = Logger.getLogger("org.lobobrowser.html.renderer.HtmlController");
	
    public static Connection getDBConnection()
    {
    	if(m_objConnection==null)
    	{
	    	try
	    	{	
	    		m_objConnection=DriverManager.getConnection("jdbc:derby:db");	    		
	    	}
	    	catch(SQLException sqle)
	    	{
            	SqlUtil.ReportSQLException(sqle);
	    	}
    	}
    	
    	return m_objConnection;
    }
    
    
	/**
	* Auto-generated main method to display this JFrame
	*/
	public static void main(String[] args) {
		if(args.length>0 && args[0]=="debug")
			IsDebug=true;				
		
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {		
				
				if(!IsDebug)	
				{
					_HtmlBlockPanelLogger.setLevel(Level.OFF);
					_HTMLLinkElementImplLogger.setLevel(Level.OFF);
					_HTMLDocumentImplLogger.setLevel(Level.OFF);
					_HTMLHtmlElementImplLogger.setLevel(Level.OFF);
					_RBlockLogger.setLevel(Level.OFF);
					_HtmlControllerLogger.setLevel(Level.OFF);
				}					

				MainWindow inst = new MainWindow();
				inst.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
				
				ResourceBundle res_strings = ResourceBundle.getBundle("strings", Locale.getDefault(),new UTF8Control());
				inst.ctlMainWindowSplitter.setResizeWeight(1.0);
				inst.ctlDictionary=new DictionaryPanel();
				inst.ctlBottomTabPane.insertTab(res_strings.getString("Dictionary"),null,inst.ctlDictionary,"",0);
				inst.ctlBottomTabPane.setSelectedComponent(inst.ctlDictionary);						
			}
		});
	}
	
	public void RestoreState()
	{		
		//this will restore application state
		File objSettingsFile=new File(_settingsFileName);
		if(objSettingsFile.exists())
		{
	         try
	         {
	            FileInputStream fileIn = new FileInputStream(_settingsFileName);
	            ObjectInputStream in = new ObjectInputStream(fileIn);
	            appState = (AppState) in.readObject();
	            in.close();
	            fileIn.close();
	        }
	        catch(IOException i)
	        {
	            i.printStackTrace();
	            return;
	        }
	        catch(ClassNotFoundException c)
	        {
	            c.printStackTrace();
	            appState=new AppState();
	            return;
	        }
	        
	        ctlMainWindowSplitter.setDividerLocation(appState.splitterLocation);
	        
			setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));	
			
	        try
	        {	        
		        for(OpenBookInfo objOpenBook : appState.arrOpenBooks)
		        {        		
					OpenBook(objOpenBook.nodeId,objOpenBook.scrollPos,"",objOpenBook.paneIndex);
		        }
	        }
	        finally
	        {
				setCursor(Cursor.getDefaultCursor());
	        }
		}	
		else
			appState=new AppState();
	}
	
	
	public MainWindow() {
		super();
		loadDriver();
		
		UIManager.put("swing.boldMetal", Boolean.FALSE);
		initGUI();
		
		addWindowListener(new WindowAdapter() {
			@Override
		    public void windowClosing(WindowEvent evt) 
			{
				WindowClosing(evt); 
			}			
			
			@Override
			public void windowOpened(WindowEvent evt)
			{
				WindowOpened(evt);
			}
		});		
	}
	
	private void WindowClosing(WindowEvent evt) 
	{		
        //close Connection
        if (m_objConnection != null)                
            try 
            {
                	m_objConnection.close();
                	m_objConnection = null;	
            } 
            catch (SQLException sqle) 
            {
            	SqlUtil.ReportSQLException(sqle);
            }
            
        try
        {
            // the shutdown=true attribute shuts down Derby
            DriverManager.getConnection("jdbc:derby:;shutdown=true");
        }
        catch (SQLException se)
        {
            if (( (se.getErrorCode() == 50000)
                    && ("XJ015".equals(se.getSQLState()) ))) {
                // we got the expected exception
            	if(IsDebug)
            		System.out.println("Derby shut down normally");
                // Note that for single database shutdown, the expected
                // SQL state is "08006", and the error code is 45000.
            } else {
                // if the error code or SQLState is different, we have
                // an unexpected exception (shutdown failed)
            	System.err.println("Derby did not shut down normally");
            }
        }
            
       	SaveState();
	}	
	
	private void WindowOpened(WindowEvent evt)
	{
		if(getDBConnection()==null)
		{
			ResourceBundle res_strings = ResourceBundle.getBundle("strings", Locale.getDefault(),new UTF8Control());
			JOptionPane.showMessageDialog(this, res_strings.getString("NoDBConnection"));
			System.exit(ABORT);
		}	
		else
			RestoreState();
	}	
	
	private void SaveState()
	{
		//save AppState data		
        appState.splitterLocation=ctlMainWindowSplitter.getDividerLocation();  
        appState.arrOpenBooks.clear();
        for(Component objComponent : ctlTopTabPane.getComponents())
        {
        	if(objComponent instanceof BookFrame)
        	{
        		BookFrame objBookFrame=(BookFrame)objComponent;
        		appState.arrOpenBooks.add(appState.new OpenBookInfo(objBookFrame.getNodeID(),
        				objBookFrame.getScrollPos(),0));
        	}
        }
        
        for(Component objComponent : ctlBottomTabPane.getComponents())
        {
        	if(objComponent instanceof BookFrame)
        	{
        		BookFrame objBookFrame=(BookFrame)objComponent;
        		appState.arrOpenBooks.add(appState.new OpenBookInfo(objBookFrame.getNodeID(),
        				objBookFrame.getScrollPos(),1));
        	}
        }
        
        try
        {
           FileOutputStream fileOut = new FileOutputStream(_settingsFileName);
           ObjectOutputStream out =new ObjectOutputStream(fileOut);
           out.writeObject(appState);
           out.close();
           fileOut.close();
        }
        catch(IOException i)
        {
            i.printStackTrace();
        }    
	}
	
	
	private void initGUI() {
		try {
				this.pack();
				GroupLayout thisLayout = new GroupLayout((JComponent)getContentPane());
				getContentPane().setLayout(thisLayout);
				this.setExtendedState(Frame.MAXIMIZED_BOTH);
				ImageIcon img = new ImageIcon("jpalireader.png");
				setIconImage(img.getImage());
				
				ResourceBundle res_strings = ResourceBundle.getBundle("strings", Locale.getDefault(),new UTF8Control());
				setTitle(res_strings.getString("AppName"));
				
			{
				ctlToolBar = new JToolBar();
				getContentPane().add(ctlToolBar, BorderLayout.NORTH);
				ctlToolBar.setFloatable(false);
				{
					final JButton ctlOpenBook = new JButton();
					FlowLayout ctlOpenBookLayout = new FlowLayout();
					ctlToolBar.add(ctlOpenBook);
					ctlOpenBook.setLayout(null);
					ctlOpenBook.setText(res_strings.getString("OpenBook"));
					ctlOpenBook.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent evt) {
							ctlOpenBookActionPerformed(evt);						}
					});
				}
				{
					ctlToggleDictionary = new JButton();
					ctlToolBar.add(ctlToggleDictionary);
					ctlToggleDictionary.setText(res_strings.getString("ToggleDictionary"));
					ctlToggleDictionary.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent evt) {
							ctlToggleDictionaryActionPerformed(evt);
						}
					});
				}
				{
					ctlSearchTipitaka = new JButton();
					ctlToolBar.add(ctlSearchTipitaka);
					ctlSearchTipitaka.setText(res_strings.getString("SearchTipitaka"));
					ctlSearchTipitaka.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent evt) {
							ctlSearchTipitakaActionPerformed(evt);
						}
					});
				}
				{
					ctlExit = new JButton();
					ctlToolBar.add(ctlExit);
					ctlExit.setText(res_strings.getString("Exit"));
					ctlExit.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent evt) {
							ctlExitActionPerformed(evt);
						}
					});
				}
			}
			{
				ctlTopTabPane = new JTabbedPane();
				//getContentPane().add(ctlTopTabPane, BorderLayout.CENTER);
				ctlTopTabPane.setTabPlacement(JTabbedPane.BOTTOM);
				ctlTopTabPane.setPreferredSize(new java.awt.Dimension(765, 0));
				//ctlTopTabPane.setPreferredSize(new Dimension(1000,1000));
				ctlBottomTabPane=new JTabbedPane();
				ctlBottomTabPane.setTabPlacement(JTabbedPane.BOTTOM);
				ctlBottomTabPane.setPreferredSize(new java.awt.Dimension(0, 0));
			}
			{
				ctlMainWindowSplitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT,ctlTopTabPane,ctlBottomTabPane);
				ctlMainWindowSplitter.setOneTouchExpandable(true);
			}
			
			
				thisLayout.setVerticalGroup(thisLayout.createSequentialGroup()
					.addComponent(ctlToolBar, GroupLayout.PREFERRED_SIZE, 35, GroupLayout.PREFERRED_SIZE)
					.addComponent(ctlMainWindowSplitter, 0, 284, Short.MAX_VALUE));
				thisLayout.setHorizontalGroup(thisLayout.createParallelGroup()
					.addComponent(ctlToolBar, GroupLayout.Alignment.LEADING, 0, 767, Short.MAX_VALUE)
					.addComponent(ctlMainWindowSplitter, GroupLayout.Alignment.LEADING, 0, 767, Short.MAX_VALUE));
				
				
			javax.swing.plaf.FontUIResource objPaliFont=new javax.swing.plaf.FontUIResource("Tahoma",java.awt.Font.PLAIN,12);
			if(objPaliFont!=null)
			{
			    java.util.Enumeration keys = UIManager.getDefaults().keys();
			    while (keys.hasMoreElements()) {
			      Object key = keys.nextElement();
			      Object value = UIManager.get (key);
			      if (value instanceof javax.swing.plaf.FontUIResource)
			        UIManager.put (key, objPaliFont);
			      }
			}
			    
			UIManager.put("OptionPane.yesButtonText", res_strings.getString("Yes"));
			UIManager.put("OptionPane.noButtonText", res_strings.getString("No"));
			UIManager.put("OptionPane.cancelButtonText", res_strings.getString("Cancel"));
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void ctlExitActionPerformed(ActionEvent evt)
	{		
		this.processWindowEvent(
	            new WindowEvent(
	                  this, WindowEvent.WINDOW_CLOSING));
	}
	
	private void ctlOpenBookActionPerformed(ActionEvent evt) {

		if(m_dlgOpenBook==null)
			m_dlgOpenBook=new OpenBookDlg(this);
		
		m_dlgOpenBook.setSize(550,450);
		m_dlgOpenBook.setLocationRelativeTo(null);
		m_dlgOpenBook.setVisible(true);
		
		if(m_dlgOpenBook.isDialogSuccess())
		{		
			OpenBook(m_dlgOpenBook.getNodeID(),m_dlgOpenBook.getScrollPos(),
					m_dlgOpenBook.getPTSPage(),m_dlgOpenBook.getTargetPaneIndex());
		}
	}
	
	public void OpenBook(int NodeID,int ScrollPos,String PTSPage,int TargetPaneIndex)
	{
		try
		{
			setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));	
			
			JTabbedPane objTabbedPane=TargetPaneIndex==0 ? ctlTopTabPane : ctlBottomTabPane;
			BookFrame objNewFrame=null;
			if(ScrollPos>0)
				objNewFrame=new BookFrame(NodeID,ScrollPos);
			else
				objNewFrame=new BookFrame(NodeID,PTSPage);
			
			objTabbedPane.insertTab(objNewFrame.getBookName(),null,objNewFrame,objNewFrame.getBookPath(),objTabbedPane.getTabCount());
			objTabbedPane.setSelectedComponent(objNewFrame);
			
			NodeInfo objDummyNode=new NodeInfo(objNewFrame.getBookNodeID(),"",0);
			ButtonTabComponent objTabButton=new ButtonTabComponent(objTabbedPane,objDummyNode.getPath());
							
			objTabbedPane.setTabComponentAt(objTabbedPane.getSelectedIndex(),
					objTabButton);
		}
		finally
		{
			setCursor(Cursor.getDefaultCursor());
		}
	}
	
    /**
     * Loads the appropriate JDBC driver for this environment/framework. For
     * example, if we are in an embedded environment, we load Derby's
     * embedded Driver, <code>org.apache.derby.jdbc.EmbeddedDriver</code>.
     */
    private static void loadDriver() {
        /*
         *  The JDBC driver is loaded by loading its class.
         *  If you are using JDBC 4.0 (Java SE 6) or newer, JDBC drivers may
         *  be automatically loaded, making this code optional.
         *
         *  In an embedded environment, this will also start up the Derby
         *  engine (though not any databases), since it is not already
         *  running. In a client environment, the Derby engine is being run
         *  by the network server framework.
         *
         *  In an embedded environment, any static Derby system properties
         *  must be set before loading the driver to take effect.
         */
        try {
            Class.forName(driver).newInstance();
            if(IsDebug)
            	System.out.println("Loaded the appropriate driver");
        } catch (ClassNotFoundException cnfe) {
            System.err.println("\nUnable to load the JDBC driver " + driver);
            System.err.println("Please check your CLASSPATH.");
            cnfe.printStackTrace(System.err);
        } catch (InstantiationException ie) {
            System.err.println(
                        "\nUnable to instantiate the JDBC driver " + driver);
            ie.printStackTrace(System.err);
        } catch (IllegalAccessException iae) {
            System.err.println(
                        "\nNot allowed to access the JDBC driver " + driver);
            iae.printStackTrace(System.err);
        }
    }
	
	public void DictionaryLookup(String strKeyword)
	{
		ctlMainWindowSplitter.setDividerLocation(ctlMainWindowSplitter.getSize().height-250);
		
		ctlBottomTabPane.setSelectedComponent(ctlDictionary);
		ctlDictionary.Lookup(strKeyword);
	}
	
	private void ctlToggleDictionaryActionPerformed(ActionEvent evt) {
		if(ctlMainWindowSplitter.getDividerLocation()>ctlMainWindowSplitter.getSize().height-250)
			ctlMainWindowSplitter.setDividerLocation(ctlMainWindowSplitter.getSize().height-250);
		else
			ctlMainWindowSplitter.setDividerLocation(ctlMainWindowSplitter.getSize().height);		
	}
	
	private void ctlSearchTipitakaActionPerformed(ActionEvent evt) 
	{		
		TipitakaSearchPanel objPanel=new TipitakaSearchPanel();
		ResourceBundle res_strings = ResourceBundle.getBundle("strings", Locale.getDefault(),new UTF8Control());
		ctlTopTabPane.addTab(res_strings.getString("SearchTipitaka"),objPanel);
		ctlTopTabPane.setSelectedComponent(objPanel);
		ctlTopTabPane.setTabComponentAt(ctlTopTabPane.getSelectedIndex(),
                 new ButtonTabComponent(ctlTopTabPane,""));
	}

	/*
	private String GetAppDir()
	{
		String applicationDir = getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); 

		if (applicationDir.endsWith(".exe"))
		{
		    applicationDir = new File(applicationDir).getParent();
		}
		else
		{
		    // Add the path to the class files  
		    applicationDir += getClass().getName().replace('.', '/');

		    // Step one level up as we are only interested in the 
		    // directory containing the class files
		    applicationDir = new File(applicationDir).getParent();
		}	
	
		return applicationDir;
	}*/
}
